package com.fzebu.fastboot.db;

import com.fzebu.fastboot.db.builder.SQLBuilderFactory;
import com.fzebu.fastboot.db.intl.AbstractSQLBuilder;
import com.fzebu.fastboot.db.intl.TransactionHandler;
import com.fzebu.fastboot.form.converter.FormConverter;
import com.fzebu.fastboot.form.converter.impl.DbFormHandler;
import com.fzebu.fastboot.form.exception.ConvertException;
import lombok.extern.slf4j.Slf4j;
import weaver.conn.RecordSetTrans;

import java.util.Arrays;
import java.util.List;

/**
 * @author Y-Aron
 * @version 1.0.0
 * @create 2019/10/8 10:24
 */
@Slf4j(topic = "debug")
public class DbUtil {

    public static <T> T query(Class<T> clazz, String sql, Object... params) {
        //noinspection unchecked
        return (T) query(clazz, true, sql, params);
    }

    public static <T> List<T> queryList(Class<T> clazz, String sql, Object... params) {
        //noinspection unchecked
        return (List<T>) query(clazz, false, sql, params);
    }

    private static <T> Object query(Class<T> clazz, boolean only, String sql, Object... params) {
        RecordSetTrans rs = new RecordSetTrans();
        log.debug("DbUtil -> Query sql: {}, params {}", sql, Arrays.toString(params));
        try {
            rs.executeQuery(sql, params);
        } catch (Exception e) {
            log.error("DbUtil -> Query data error! msg: {}", e.getMessage());
            return null;
        }
        FormConverter converter = FormConverter.builder(clazz)
                .rst(rs)
                .build();
        try {
            if (only) {
                return converter.toJavaBean(new DbFormHandler());
            } else {
                return converter.toJavaArray(new DbFormHandler());
            }
        } catch (ConvertException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static boolean execute(AbstractSQLBuilder sqlBuilder) {
        return sqlBuilder.executeUpdate();
    }

    public static boolean insert(Object object){
        AbstractSQLBuilder builder = SQLBuilderFactory.getSqlBuilder(object);
        return execute(builder);
    }

    public static void beginTrans(TransactionHandler t) {
        RecordSetTrans rst = new RecordSetTrans();
        rst.setAutoCommit(false);
        log.debug("Begin SQL Trans");
        try {
            t.handler(rst);
            log.debug("SQL Trans Commit => {}", rst.commit());
        } catch (Exception e) {
            log.error("Database Operation Failed => {}", e.getMessage());
            log.error("Database Begin Rollback => {}", rst.rollback());
        }
    }
}
